﻿using Mes.Application.DTO.Inputs.Operations;
using Mes.Application.DTO.Results.Operations;
using Mes.Domain.BoundedContext;
using AutoMapper;
using Mes.Infrastructure.Data.BoundedContext.RepositoryBase;
using Mes.Domain.BoundedContext.Entities.Operations;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Mes.Infrastructure.Data.BoundedContext.Extensions;
using Mes.Application.Common;
using Mes.Application.Common.Resource;

namespace Mes.Application.Services.Operations
{
    public class AttrService : IAttrService
    {
        private readonly INoIdRepository<Attr> _attrRepository;
        private readonly IMapper _mapper;
        public AttrService(INoIdRepository<Attr> attrRepository, IMapper mapper)
        {
            if (attrRepository == null || mapper == null)
            {
                throw new ArgumentNullException();
            }
            _attrRepository = attrRepository; //注入仓储类
            _mapper = mapper;
        }
        /// <summary>
        /// 添加属性
        /// </summary>
        /// <param name="attrInput"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        public async Task AddAttributeAsync(AttrInput attrInput)
        {
            var attr = _mapper.Map<Attr>(attrInput);
            if (attr == null)
            {
                throw new CustomException(Messages.AttrAdditionFailure);
            }
            await _attrRepository.AddAsync(attr);
            int status = await _attrRepository.SaveAsync();
            if (status <= 0)
            {
                throw new CustomException(Messages.SavingFailure);
            }
        }

        /// <summary>
        /// 编辑属性
        /// </summary>
        /// <param name="attrUpdateInput"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        public async Task UpdateAttributeAsync(AttrUpdateInput attrUpdateInput)
        {
            var attr = _attrRepository.Find(x => x.Attr_Id == attrUpdateInput.Attr_Id);
            if (attr == null)
            {
                throw new CustomException(Messages.AttrNotFound);
            }
            attr.Last_Edit_At = DateTime.Now;
            attr.Attr_Desc = attrUpdateInput.Attr_Desc;
            attr.Data_Type = attrUpdateInput.Data_Type;
            _attrRepository.Update(attr);
            int status = await _attrRepository.SaveAsync();
            if (status <= 0)
            {
                throw new CustomException(Messages.SavingFailure);
            }
        }

        /// <summary>
        /// 删除属性
        /// </summary>
        /// <param name="attr_ids"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        public async Task DeleteAttributeAsync(int[] attr_ids)
        {
            Expression<Func<Attr, bool>> filter = x => attr_ids.Contains(x.Attr_Id);
            if (filter == null)
            {
                throw new CustomException(Messages.AttrNotFound);
            }
            await _attrRepository.DeleteAsync(filter);
            int status = await _attrRepository.SaveAsync();
            if (status <= 0)
            {
                throw new CustomException(Messages.SavingFailure);
            }
        }

        /// <summary>
        /// 查询指定属性
        /// </summary>
        /// <param name="attr_id"></param>
        /// <returns>AttrResult</returns>
        /// <exception cref="CustomException"></exception>
        public async Task<AttrResult> GetAttributeAsync(int attr_id)
        {
            var attr = await _attrRepository.Query().Where(x => x.Attr_Id == attr_id).FirstOrDefaultAsync();
            if (attr == null)
            {
                throw new CustomException(Messages.AttrNotFound);
            }
            return _mapper.Map<AttrResult>(attr);
        }

        /// <summary>
        /// 分页查询属性
        /// </summary>
        /// <param name="attrPageInput"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        public async Task<PagedItemsData<AttrResult>> GetAttributesAsync(AttrPageInput attrPageInput)
        {
            Expression<Func<Attr, bool>> filter = x => true;
            if (attrPageInput.Attr_Id >= 0)
            {
                filter = x => x.Attr_Id == attrPageInput.Attr_Id;
            }
            var attr = await _attrRepository.Query().Where(filter).ToPagedAsync(attrPageInput.PagedInput);
            if (attr == null)
            {
                throw new CustomException(Messages.AttrNotFound);
            }
            return _mapper.Map<PagedItemsData<AttrResult>>(attr);
        }
    }
}
